local DIY = require "packages/diy_utility/diy_utility"

local fuhai = fk.CreateSkill{
  name = "investiture__fuhai",
  tags = {"Phase"},
}

Fk:loadTranslationTable{
  ["investiture__fuhai"] = "覆海",
  [":investiture__fuhai"] = "阶段技，你可获得中央区内一张【杀】或【闪】；"
  .."或令一名其他角色选择一项：1.用三张手牌交换中央区内一张【杀】；2.用一张其场上的牌交换中央区内一张【闪】。",
  ["#investiture__fuhai"] = "覆海：可以选择中央区内一张【杀】或【闪】获得，或令一名其他角色选择一项",

  ["investiture__fuhai_poxi"] = "覆海",
  ["#investiture__fuhai_poxi"] = "覆海：用三张手牌交换中央区内一张【杀】，或用场上的一张牌交换中央区内一张【闪】"
}

---@param room AbstractRoom
---@param names string[]
---@return integer[]
local getCenter = function (room, names)
  return table.filter(DIY.getCenterCards(room), function (id)
    return table.contains(names, Fk:getCardById(id).trueName)
  end)
end

Fk:addPoxiMethod{
  name = "investiture__fuhai_poxi",
  prompt = "#investiture__fuhai_poxi",
  card_filter = Util.TrueFunc,
  feasible = function (selected, data, extra_data)
    local map = {{}, {}, {}, {}, {}, {}, {}}
    for _, id in ipairs(selected) do
      table.insert(map[Fk:currentRoom():getCardArea(id)], id)
    end
    if #map[Card.DiscardPile] ~= 1 then return false end
    if Fk:getCardById(map[Card.DiscardPile][1]).trueName == "slash" then
      return #selected == 4 and #map[Card.PlayerHand] == 3
    else
      return #selected == 2 and #map[Card.PlayerEquip] + #map[Card.PlayerJudge] == 1
    end
  end,
  default_choice = function (data)
    local slash, jink, hands, on_fild = nil, nil, nil, nil
    for _, d in ipairs(data) do
      if d[1] == "$Hand" then
        if #d[2] >= 3 then
          hands = table.slice(d[2], 1, 4)
        end
      elseif d[1] == "$CenterArea" then
        slash = table.find(d[2], function (id) return Fk:getCardById(id).trueName == "slash" end)
        jink = table.find(d[2], function (id) return Fk:getCardById(id).trueName == "jink" end)
      else
        on_fild = d[2][1]
      end
    end
    if slash and hands then
      return table.connect(hands, { slash })
    else
      return { on_fild, jink }
    end
  end
}

fuhai:addAcquireEffect(function (self, player, is_start)
  player.room:addSkill("#CenterArea")
end)

fuhai:addEffect("active", {
  mute = true,
  prompt = "#investiture__fuhai",
  can_use = function (self, player)
    return player:usedSkillTimes(fuhai.name, Player.HistoryPhase) == 0
  end,
  expand_pile = function (self, player)
    return getCenter(Fk:currentRoom(), {"slash", "jink"})
  end,
  card_filter = function (self, player, to_select, selected)
    return #selected == 0 and table.contains(getCenter(Fk:currentRoom(), {"slash", "jink"}), to_select)
  end,
  target_filter = function (self, player, to_select, selected, selected_cards)
    if #selected_cards == 0 and #selected == 0 then
      return to_select ~= player
      and ( (to_select:getHandcardNum() >= 3 and #getCenter(Fk:currentRoom(), {"slash"}) > 0)
      or (#to_select:getCardIds("ej") > 0 and #getCenter(Fk:currentRoom(), {"jink"}) > 0) )
    end
  end,
  feasible = function (self, player, selected, selected_cards)
    return #selected_cards + #selected == 1
  end,
  on_use = function (self, room, effect)
    local player = effect.from
    local cards = effect.cards
    local tos = effect.tos
    if #tos == 1 then
      room:notifySkillInvoked(player, fuhai.name, "control")
      player:broadcastSkillInvoke(fuhai.name, math.random(3,4))
      local data = {}
      local areas = {
        {Card.PlayerHand, "$Hand"},
        {Card.PlayerEquip, "$Equip"},
        {Card.PlayerJudge, "$Judge"},
      }
      for _, e in ipairs(areas) do
        if #tos[1]:getCardIds(e[1]) > 0 then
          table.insert(data, {e[2], tos[1]:getCardIds(e[1])})
        end
      end
      table.insert(data, {"$CenterArea", getCenter(room, {"slash", "jink"})})

      local ret = room:askToPoxi(tos[1], {
        poxi_type = "investiture__fuhai_poxi",
        data = data,
        cancelable = false,
      })
      local from_center = table.find(ret, function (id)
        return room:getCardArea(id) == Card.DiscardPile
      end)
      local from_player = table.filter(ret, function (id)
        return id ~= from_center
      end)
      room:moveCards({
        ids = {from_center},
        to = tos[1],
        toArea = Card.PlayerHand,
        proposer = tos[1],
        moveReason = fk.ReasonExchange,
        skillName = fuhai.name,
        moveVisible = true,
      }, {
        ids = from_player,
        from = tos[1],
        toArea = Card.DiscardPile,
        proposer = tos[1],
        moveReason = fk.ReasonExchange,
        skillName = fuhai.name,
        moveVisible = true,
      })
    elseif #cards == 1 then
      room:notifySkillInvoked(player, fuhai.name, "drawcard")
      player:broadcastSkillInvoke(fuhai.name, math.random(1,2))
      room:obtainCard(player, cards, true, fk.ReasonJustMove)
    end
  end
})

return fuhai